package com.ioftv.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ioftv.common.Result;
import com.ioftv.dto.LabelerDailyOutputExcelDTO;
import com.ioftv.entity.LabelerDailyOutput;
import com.ioftv.listener.LabelerDailyOutputImportListener;
import com.ioftv.service.LabelerDailyOutputService;
import com.ioftv.util.UserContextUtil;
import com.ioftv.util.RolePermissionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 标注员每日产值记录Controller
 */
@Slf4j
@RestController
@RequestMapping("/admin")
public class LabelerDailyOutputController {

    @Autowired
    private LabelerDailyOutputService labelerDailyOutputService;

    /**
     * 3.1 分页查询标注员每日产值记录列表
     * 接口地址：GET /admin/labeler-daily-output
     */
    @GetMapping("/labeler-daily-output")
    public Result<Page<LabelerDailyOutput>> getLabelerDailyOutputList(
            @RequestParam Integer currentPage,
            @RequestParam Integer pageSize,
            @RequestParam(required = false) String labelerName,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 创建分页对象
        Page<LabelerDailyOutput> page = new Page<>(currentPage, pageSize);
        
        // 构建查询条件
        LambdaQueryWrapper<LabelerDailyOutput> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加用户ID条件（管理员可查看所有数据）
        if (!RolePermissionUtil.isAdmin(role)) {
            queryWrapper.eq(LabelerDailyOutput::getUserId, userId);
        }
        
        if (labelerName != null && !labelerName.trim().isEmpty()) {
            queryWrapper.like(LabelerDailyOutput::getLabelerName, labelerName);
        }
        if (startDate != null && !startDate.trim().isEmpty()) {
            LocalDate start = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            queryWrapper.ge(LabelerDailyOutput::getRecordDate, start);
        }
        if (endDate != null && !endDate.trim().isEmpty()) {
            LocalDate end = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            queryWrapper.le(LabelerDailyOutput::getRecordDate, end);
        }
        queryWrapper.orderByDesc(LabelerDailyOutput::getRecordDate);
        
        // 执行分页查询
        Page<LabelerDailyOutput> resultPage = labelerDailyOutputService.page(page, queryWrapper);
        
        return Result.success(resultPage);
    }

    /**
     * 3.2 新增标注员每日产值记录
     * 接口地址：POST /admin/labeler-daily-output
     */
    @PostMapping("/labeler-daily-output")
    public Result<LabelerDailyOutput> addLabelerDailyOutput(@RequestBody LabelerDailyOutput record, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 设置用户ID
        record.setUserId(userId);
        
        // 参数校验
        if (record.getLabelerId() == null) {
            return Result.error("标注员ID不能为空");
        }
        if (record.getLabelerName() == null || record.getLabelerName().trim().isEmpty()) {
            return Result.error("标注员姓名不能为空");
        }
        if (record.getRecordDate() == null) {
            return Result.error("记录日期不能为空");
        }
        if (record.getTargetBoxCount() == null) {
            return Result.error("应达到框数不能为空");
        }
        if (record.getActualBoxCount() == null) {
            return Result.error("实际框数不能为空");
        }
        
        // 业务逻辑校验：当应达到框数大于实际框数时，未完成原因必须填写
        if (record.getTargetBoxCount() > record.getActualBoxCount() && 
            (record.getUncompletedReason() == null || record.getUncompletedReason().trim().isEmpty())) {
            return Result.error("参数错误：当应达到框数大于实际框数时，必须填写未完成原因");
        }
        
        // 保存数据
        boolean success = labelerDailyOutputService.save(record);
        if (success) {
            return Result.success(record);
        } else {
            return Result.error("新增失败");
        }
    }

    /**
     * 3.3 修改标注员每日产值记录
     * 接口地址：PUT /admin/labeler-daily-output/{id}
     */
    @PutMapping("/labeler-daily-output/{id}")
    public Result<LabelerDailyOutput> updateLabelerDailyOutput(@PathVariable Long id, @RequestBody LabelerDailyOutput record, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 检查数据是否存在且属于当前用户
        LambdaQueryWrapper<LabelerDailyOutput> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LabelerDailyOutput::getId, id);
        // 添加用户ID条件（管理员可查看所有数据）
        if (!RolePermissionUtil.isAdmin(role)) {
            queryWrapper.eq(LabelerDailyOutput::getUserId, userId);
        }
        
        LabelerDailyOutput existing = labelerDailyOutputService.getOne(queryWrapper);
        if (existing == null) {
            return Result.error(404, "数据不存在或无权限访问");
        }
        
        // 设置ID
        record.setId(id);
        // 保持用户ID不变
        record.setUserId(existing.getUserId());
        
        // 参数校验
        if (record.getLabelerId() == null) {
            return Result.error("标注员ID不能为空");
        }
        if (record.getLabelerName() == null || record.getLabelerName().trim().isEmpty()) {
            return Result.error("标注员姓名不能为空");
        }
        if (record.getRecordDate() == null) {
            return Result.error("记录日期不能为空");
        }
        if (record.getTargetBoxCount() == null) {
            return Result.error("应达到框数不能为空");
        }
        if (record.getActualBoxCount() == null) {
            return Result.error("实际框数不能为空");
        }
        
        // 业务逻辑校验：当应达到框数大于实际框数时，未完成原因必须填写
        if (record.getTargetBoxCount() > record.getActualBoxCount() && 
            (record.getUncompletedReason() == null || record.getUncompletedReason().trim().isEmpty())) {
            return Result.error("参数错误：当应达到框数大于实际框数时，必须填写未完成原因");
        }
        
        // 更新数据
        boolean success = labelerDailyOutputService.updateById(record);
        if (success) {
            // 重新查询返回最新数据
            LabelerDailyOutput updated = labelerDailyOutputService.getOne(queryWrapper);
            return Result.success(updated);
        } else {
            return Result.error("修改失败");
        }
    }

    /**
     * 3.4 删除标注员每日产值记录
     * 接口地址：DELETE /admin/labeler-daily-output/{id}
     */
    @DeleteMapping("/labeler-daily-output/{id}")
    public Result<Void> deleteLabelerDailyOutput(@PathVariable Long id, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 检查数据是否存在且属于当前用户
        LambdaQueryWrapper<LabelerDailyOutput> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LabelerDailyOutput::getId, id);
        // 添加用户ID条件（管理员可查看所有数据）
        if (!RolePermissionUtil.isAdmin(role)) {
            queryWrapper.eq(LabelerDailyOutput::getUserId, userId);
        }
        
        LabelerDailyOutput existing = labelerDailyOutputService.getOne(queryWrapper);
        if (existing == null) {
            return Result.error(404, "数据不存在或无权限访问");
        }
        
        // 删除数据
        boolean success = labelerDailyOutputService.removeById(id);
        if (success) {
            return Result.success(null);
        } else {
            return Result.error("删除失败");
        }
    }

    /**
     * 3.5 获取标注员每日产值统计图表数据
     * 接口地址：GET /admin/labeler-daily-output/chart-data
     */
    @GetMapping("/labeler-daily-output/chart-data")
    public Result<Map<String, Object>> getChartData(
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        // 构建查询条件
        LambdaQueryWrapper<LabelerDailyOutput> queryWrapper = new LambdaQueryWrapper<>();
        // 添加用户ID条件（管理员可查看所有数据）
        if (!RolePermissionUtil.isAdmin(role)) {
            queryWrapper.eq(LabelerDailyOutput::getUserId, userId);
        }
        if (startDate != null && !startDate.trim().isEmpty()) {
            LocalDate start = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            queryWrapper.ge(LabelerDailyOutput::getRecordDate, start);
        }
        if (endDate != null && !endDate.trim().isEmpty()) {
            LocalDate end = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            queryWrapper.le(LabelerDailyOutput::getRecordDate, end);
        }
        
        // 查询数据
        List<LabelerDailyOutput> records = labelerDailyOutputService.list(queryWrapper);
        
        // 按标注员姓名分组统计实际框数
        Map<String, Integer> labelerBoxCountMap = new HashMap<>();
        for (LabelerDailyOutput record : records) {
            String labelerName = record.getLabelerName();
            Integer actualBoxCount = record.getActualBoxCount();
            labelerBoxCountMap.put(labelerName, labelerBoxCountMap.getOrDefault(labelerName, 0) + actualBoxCount);
        }
        
        // 构造返回结果
        List<String> labelerNames = new ArrayList<>(labelerBoxCountMap.keySet());
        List<Integer> actualBoxCounts = labelerNames.stream()
                .map(labelerBoxCountMap::get)
                .collect(Collectors.toList());
        
        Map<String, Object> result = new HashMap<>();
        result.put("labelerNames", labelerNames);
        result.put("actualBoxCounts", actualBoxCounts);
        
        return Result.success(result);
    }
    
    /**
     * 下载Excel导入模板
     * 接口地址：GET /admin/labeler-daily-output/template
     */
    @GetMapping("/labeler-daily-output/template")
    public void downloadTemplate(HttpServletResponse response, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("标注员每日产值记录导入模板", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 创建空模板（只有表头）
            List<LabelerDailyOutputExcelDTO> templateData = new ArrayList<>();

            // 写入Excel（只生成表头，不含数据）
            EasyExcel.write(response.getOutputStream(), LabelerDailyOutputExcelDTO.class)
                    .sheet("标注员每日产值记录")
                    .doWrite(templateData);

            log.info("下载Excel模板成功");
        } catch (IOException e) {
            log.error("下载Excel模板失败", e);
            throw new RuntimeException("下载模板失败: " + e.getMessage());
        }
    }

    /**
     * 批量导入Excel数据
     * 接口地址：POST /admin/labeler-daily-output/import
     */
    @PostMapping("/labeler-daily-output/import")
    public Result<Void> importExcel(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        if (file == null || file.isEmpty()) {
            return Result.error("请选择要导入的文件");
        }

        String fileName = file.getOriginalFilename();
        if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
            return Result.error("仅支持Excel文件格式（.xlsx或.xls）");
        }

        try {
            log.info("开始导入Excel文件: {}", fileName);

            // 使用监听器模式读取Excel，支持大文件
            LabelerDailyOutputImportListener listener = new LabelerDailyOutputImportListener(labelerDailyOutputService);
            listener.setUserId(userId); // 设置用户ID用于数据隔离
            
            EasyExcel.read(file.getInputStream(), 
                          LabelerDailyOutputExcelDTO.class, 
                          listener)
                    .sheet()
                    .doRead();

            log.info("导入完成");
            return Result.success(null);

        } catch (IOException e) {
            log.error("导入Excel文件失败", e);
            return Result.error("导入失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("导入Excel文件异常", e);
            return Result.error("导入异常: " + e.getMessage());
        }
    }
    
    /**
     * 导出Excel数据
     * 接口地址：GET /admin/labeler-daily-output/export
     */
    @GetMapping("/labeler-daily-output/export")
    public void exportExcel(
            @RequestParam(required = false) String labelerName,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            HttpServletResponse response,
            HttpServletRequest request) {
        // 获取当前用户信息
        Long userId = UserContextUtil.getCurrentUserId(request);
        String username = UserContextUtil.getCurrentUsername(request);
        String role = UserContextUtil.getCurrentUserRole(request);
        
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("标注员每日产值记录_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")), "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 构建查询条件
            LambdaQueryWrapper<LabelerDailyOutput> queryWrapper = new LambdaQueryWrapper<>();
            // 添加用户ID条件（管理员可查看所有数据）
            if (!RolePermissionUtil.isAdmin(role)) {
                queryWrapper.eq(LabelerDailyOutput::getUserId, userId);
            }
            if (labelerName != null && !labelerName.trim().isEmpty()) {
                queryWrapper.like(LabelerDailyOutput::getLabelerName, labelerName);
            }
            if (startDate != null && !startDate.trim().isEmpty()) {
                LocalDate start = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                queryWrapper.ge(LabelerDailyOutput::getRecordDate, start);
            }
            if (endDate != null && !endDate.trim().isEmpty()) {
                LocalDate end = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                queryWrapper.le(LabelerDailyOutput::getRecordDate, end);
            }
            queryWrapper.orderByDesc(LabelerDailyOutput::getRecordDate);
            
            // 查询数据
            List<LabelerDailyOutput> recordList = labelerDailyOutputService.list(queryWrapper);
            
            // 转换为Excel DTO
            List<LabelerDailyOutputExcelDTO> excelDataList = new ArrayList<>();
            for (LabelerDailyOutput record : recordList) {
                LabelerDailyOutputExcelDTO excelDTO = new LabelerDailyOutputExcelDTO();
                excelDTO.setLabelerId(record.getLabelerId());
                excelDTO.setLabelerName(record.getLabelerName());
                excelDTO.setRecordDate(record.getRecordDate());
                excelDTO.setTargetBoxCount(record.getTargetBoxCount());
                excelDTO.setActualBoxCount(record.getActualBoxCount());
                excelDTO.setUncompletedReason(record.getUncompletedReason());
                excelDataList.add(excelDTO);
            }

            // 写入Excel
            EasyExcel.write(response.getOutputStream(), LabelerDailyOutputExcelDTO.class)
                    .sheet("标注员每日产值记录")
                    .doWrite(excelDataList);

            log.info("导出Excel成功，共导出{}条数据", excelDataList.size());
        } catch (IOException e) {
            log.error("导出Excel失败", e);
            throw new RuntimeException("导出失败: " + e.getMessage());
        }
    }
}